package cemp.service;

import cemp.bean.OOMObject;
import cemp.common.api.reponse.*;
import cemp.common.dto.response.CommonOption;
import cemp.common.util.DateUtil;
import cemp.common.util.StockCopyPropertyUtil;
import cemp.entity.StockAll;
import cemp.entity.StockAvg;
import cemp.entity.StockKpiDay;
import cemp.entity.StockPlate;
import cemp.mapper.StockAllMapper;
import cemp.mapper.StockAvgMapper;
import cemp.mapper.StockKpiDayMapper;
import cemp.mapper.StockPlateMapper;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class KpiService {

    private final StockAllMapper stockAllMapper;
    private final StockKpiDayMapper stockKpiDayMapper;
    private final StockAvgMapper stockAvgMapper;
    private final StockPlateMapper stockPlateMapper;
    private final StockCommonUtil stockCommonUtil;

    public List<String> getSmooth(String staDate ,Integer days){



        return null;
    }

    public List<String> getDecrease3(String staDate,Integer interval){
        LocalDate lEndDate = DateUtil.str2LocalDate(staDate).plusDays(1);
        String startDate = DateUtil.localDate2Str(lEndDate.minusDays(interval *2));
        String endDate = DateUtil.localDate2Str(lEndDate);
        List<StockKpiDay> stocks =  stockKpiDayMapper.getLatest2(startDate,endDate);
        Map<String,List<StockKpiDay>> map =  stocks.stream().collect(Collectors.groupingBy(StockKpiDay::getStockCode));
        Map<String,List<StockKpiDay>> newMap = new HashMap<>();
        map.forEach(new BiConsumer<String, List<StockKpiDay>>() {
            @Override
            public void accept(String stockCode, List<StockKpiDay> stockKpiDays) {
                //取最近的三条数据
                List<StockKpiDay> newList= stockKpiDays.stream().sorted(new Comparator<StockKpiDay>() {
                    @Override
                    public int compare(StockKpiDay o1, StockKpiDay o2) {
                        return o2.getStaDate().compareTo(o1.getStaDate());
                    }
                }).limit(3).filter(kpi -> kpi.getPriceIncrease().compareTo(BigDecimal.ZERO) < 0).collect(Collectors.toList());
                if(newList != null && newList.size() == 3){
                    newMap.put(stockCode,newList);
                }
            }
        });
        return newMap.keySet().stream().toList();
    }

    public List<String> avgSmooth(String staDate,Integer interval){
        //查询统计日期内的数据
        LocalDate lEndDate = DateUtil.str2LocalDate(staDate).plusDays(1);
        String endDate = DateUtil.localDate2Str(lEndDate);
        String startDate = DateUtil.localDate2Str(lEndDate.minusDays(interval * 2));
        //查最近30天
        List<StockAvg> avg30 =  stockAvgMapper.getLatest(endDate,startDate);
        Map<String,List<StockAvg>> avgMap = avg30.stream().collect(Collectors.groupingBy(StockAvg::getStockCode));
        List<String> filterList = new ArrayList<>();
        avgMap.forEach(new BiConsumer<String, List<StockAvg>>() {
            @Override
            public void accept(String stockCode, List<StockAvg> stockAvgs) {
                if(stockCode.equals("002480")){
                    System.out.println("success");
                }
                if(stockAvgs != null &&stockAvgs.size() >=interval){
                    Collections.reverse(stockAvgs);
                    stockAvgs = stockAvgs.subList(0,interval-1);
                }
                List<StockAvg> sortedList10 =  stockAvgs.stream().sorted((o1, o2) -> o1.getAvgTen().compareTo(o2.getAvgTen())).collect(Collectors.toList());
                BigDecimal avg10Min = sortedList10.get(0).getAvgTen();
                BigDecimal avg10Max = sortedList10.get(sortedList10.size()-1).getAvgTen();
                //BigDecimal avg10Max = sortedList10.get(29).getAvgTen();

                List<StockAvg> sortedList20 =  stockAvgs.stream().sorted((o1, o2) -> o1.getAvgTwenty().compareTo(o2.getAvgTwenty())).collect(Collectors.toList());
                BigDecimal avg20Min = sortedList20.get(0).getAvgTwenty();
                BigDecimal avg20Max = sortedList20.get(sortedList20.size()-1).getAvgTwenty();

                List<StockAvg> sortedList30 =  stockAvgs.stream().sorted((o1, o2) -> o1.getAvgThirty().compareTo(o2.getAvgThirty())).collect(Collectors.toList());

                BigDecimal avg30Min = sortedList30.get(0).getAvgThirty();
                BigDecimal avg30Max = sortedList30.get(sortedList30.size()-1).getAvgThirty();

                List<StockAvg> sortedList60 =  stockAvgs.stream().sorted((o1, o2) -> o1.getAvgSixty().compareTo(o2.getAvgSixty())).collect(Collectors.toList());
                BigDecimal avg60Min = sortedList60.get(0).getAvgSixty();
                BigDecimal avg60Max = sortedList60.get(sortedList60.size()-1).getAvgSixty();

                BigDecimal s1 = NumberUtil.div(avg10Max,avg10Min,2, RoundingMode.HALF_UP);
                boolean smooth10 = NumberUtil.div(avg10Max,avg10Min,2, RoundingMode.HALF_UP).compareTo(new BigDecimal(1.1)) < 0;
                boolean smooth20 = NumberUtil.div(avg20Max,avg20Min,2, RoundingMode.HALF_UP).compareTo(new BigDecimal(1.08)) < 0;
                boolean smooth30 = NumberUtil.div(avg30Max,avg30Min,2, RoundingMode.HALF_UP).compareTo(new BigDecimal(1.06)) < 0;
                boolean smooth60 = NumberUtil.div(avg60Max,avg60Min,2, RoundingMode.HALF_UP).compareTo(new BigDecimal(1.05)) < 0;

                if(smooth10 && smooth20 && smooth30 && smooth60){
                    filterList.add(stockCode);
                }
            }
        });
        return filterList;

    }

    public List<RestStockResult> getIncrease3(String staDate){


        return null;
    }


}
